
import time
import requests
import json
from wechatpy.oauth import WeChatOAuth

from flask import g, current_app, request, make_response, jsonify
from flask_restplus import Resource, marshal
from sqlalchemy import or_

# 业务代码
from hzb.database import db
from hzb.common.common import allow_cross_domain
from hzb.auth import auth
from hzb.users import users_api, users_ns
from hzb.users.model.users_model import UsersModel
from hzb.common.field import BaseResp
from hzb.wx.wx_unionid_manage import WxUnionIdManageModel
from hzb.label.logic.label_logic import LabelLogic

# 模块内部
from ..filed.user_filed import UserLoginResp, UserGetTokenReq, GetTokenByCodeReq, SetUserInfoReq


# auth全局验证验证密码方法
# options没办法进来
# 同时把对应的user对象放到g中
@auth.verify_password
def verify_password(user_id, union_id):
    print("verify_password", user_id, union_id)
    # 先验证是否使用了token
    user = UsersModel.verify_auth_token(user_id)
    if not user:
        user = UsersModel.query.filter_by(id=user_id).first()
        if user is None or user.verify_password(union_id) is False:
            print("auth verify_password user failed!")
            return False
    g.user = user
    return True


@auth.error_handler
def auth_error_handler():
    _obj = dict()
    _obj['status'] = 403
    _obj['message'] = 'token认证失败'
    return make_response(jsonify(marshal(_obj, BaseResp)), 403)
    pass


# 登录,返回token
@users_ns.route('/login')
class Login(Resource):
    # 格式化返回数据
    @auth.login_required
    @users_ns.marshal_with(UserLoginResp)
    def post(self):
        """
        获取直播类型列表。输出：LiveTypesResp
        请参考 POSTMAN 的 Authorization 的 Basic Auth方式传值
        """
        token = g.user.generate_auth_token()
        g.user.token = token
        db.session.commit()
        _obj = dict()
        _obj['token'] = token
        _obj['user_id'] = g.user.id
        return _obj
        pass


# 注册,返回token
@users_ns.route('/register')
class Register(Resource):
    # 格式化返回数据
    @users_ns.marshal_with(BaseResp)
    def post(self):
        """
        获取直播类型列表。输出：LiveTypesResp
        请参考 POSTMAN 的 Authorization 的 Basic Auth方式传值
        """
        phone = request.json.get('phone')
        password = request.json.get('password')
        if UsersModel.query.filter_by(phone=phone).first() is not None:
            _obj = dict()
            _obj['status'] = 610
            _obj['message'] = '用户已存在'
            return _obj
        # # 先把用户添加到数据库
        user = UsersModel(phone, password)
        db.session.add(user)
        db.session.commit()
        return dict()


# 已登录获取token
@users_ns.route('/get_token')
class GetToken(Resource):
    # 格式化返回数据
    @users_ns.expect(UserGetTokenReq, validate=True)
    @users_ns.marshal_with(UserLoginResp)
    def post(self):
        """
        已经登录,获取token,仅仅供PHP服务器端调用

        """
        user_id = request.json.get('user_id')
        password = request.json.get('password')
        unionid = request.json.get('unionid')
        user = UsersModel.query.filter(or_(UsersModel.id == user_id, UsersModel.unionid == unionid)).first()
        resp = dict()
        if user is not None:
            if user.password == password:
                user.token = user.generate_auth_token()
                db.session.commit()
                resp['token'] = user.token
                return resp
        resp['status'] = 403
        resp['message'] = '密码验证失败'
        return resp


# 根据code获取union_id
@users_ns.route('/get_token_by_code')
class GetTokenByCode(Resource):
    # 格式化返回数据
    @users_ns.expect(GetTokenByCodeReq, validate=True)
    @users_ns.marshal_with(UserLoginResp)
    def post(self):
        """

        """
        _code = request.json.get("code")
        r_dict = dict()
        # 小程序获取openid
        _access_url = current_app.config['WX_GET_ACCESS_TOKEN_URL'] % (current_app.config['WX_APP_ID'],
                                                                       current_app.config['WX_APP_SECRET'], _code)
        _response = requests.get(_access_url)
        if _response.status_code == 200:
            print(_response.text)
            _res_json = json.loads(_response.text)
            _openid = _res_json['openid']
            _user = UsersModel.query.filter_by(wx_union_id=_openid).first()
            if _user is None:
                _user = UsersModel()
                _user.create_time = int(time.time())
                _user.name = ""
                _user.icon = ""
                _user.wx_union_id = _openid
                db.session.add(_user)
                _new_unionid = WxUnionIdManageModel()
                _new_unionid.create_time = int(time.time())
                _new_unionid.union_id = _openid
                db.session.add(_new_unionid)
                db.session.commit()
                LabelLogic().setDefaultLabel(_user.id)
            _result = dict()
            _result['user_id'] = _user.id
            _result['token'] = _user.generate_auth_token()
            return _result
        else:
            _result=dict()
            _result['status'] = 600
            _result['message'] = "code码无效"
            return _result
    pass


# 设置用户头像
@users_ns.route('/set_user_info')
class SetUserInfo(Resource):
    # 格式化返回数据
    @auth.login_required
    @users_ns.expect(SetUserInfoReq, validate=True)
    @users_ns.marshal_with(BaseResp)
    def post(self):
        """
        """
        _name = request.json.get("name")
        _city = request.json.get("city")
        _sex = request.json.get("sex")
        _icon = request.json.get("icon")
        _user_id = g.user.id
        _user = UsersModel.query.filter_by(id=_user_id).first()
        _user.name = _name
        _user.icon = _icon
        _user.city = _city
        _user.sex = _sex
        db.session.commit()
        return dict()
    pass

